/*
 * TMap Designer - A Thematic Map design software
 * Copyright (C) 2006 World Health Organization
 * http://www.who.int
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */
package who.tmap.ui.util;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

import org.apache.log4j.Logger;

import who.tmap.bo.AttrDef;
import who.tmap.bo.Attrs;
import who.tmap.bo.ThematicMap;
import who.tmap.bo.impl.BizObjectFactory;
import who.tmap.common.TMapException;

public class ExcelMacroHelper {

    private static Logger logger = Logger.getLogger(ExcelMacroHelper.class);
    
    private static final String JOIN_ID ="Join id";
    private static final String VALUE ="Value";
    private static final String POLYGON_NAME ="Polygon name";
    
    private static final BizObjectFactory bof =BizObjectFactory.getInstance();
	
    private static final String separator ="\";\"";
	private BufferedReader in;
	
	private String tmapSourceFileName;
	private String imageTargetFileName;
	private String tmapReturnFileName;
	private Attrs attrs;	
	
	public String getTmapSourceFileName() {
		return tmapSourceFileName;
	}	

	public String getImageTargetFileName() {
		return imageTargetFileName;
	}
	
	public Attrs getAttrs() {
		return attrs;
	}
	
	public void generateThematicMap( ThematicMap thematicMap ) {
		thematicMap.setData( attrs );
		
		thematicMap.getCartographicDisplay().setJoinIdColumnName(JOIN_ID);
		thematicMap.getCartographicDisplay().setDataColumnName(VALUE);
	}

	public void generateThematicMapFromExcelMacro( String fileName ) throws TMapException {
		try {
			openFile( fileName );
			
			readFile();
			
			/*ThematicMap thematicMap =loadThematicMap();
			thematicMap.setData( attrs );
			
			thematicMap.getCartographicDisplay().setJoinIdColumnName(JOIN_ID);
			thematicMap.getCartographicDisplay().setDataColumnName(VALUE);*/

		} catch( Exception e ) {
			logger.error( e );
			
			throw new TMapException( e );
		} finally {
			closeFile();
		}
	}
	
	public void generateReturnCodeFile( Integer errCode, String errMsg ) {
	    try {
	        BufferedWriter out = new BufferedWriter( new FileWriter( tmapReturnFileName ) );
	        
	        out.write( errCode.toString() );
	        out.newLine();
	        out.write( errMsg );
	        out.newLine();
	        out.flush();
	        out.close();
	        
	    } catch (Exception e) {
	    	logger.error(e);
	    }

	}
	
    /**
     * Open text file for input
     */
    private void openFile( String fileName ) throws Exception {
    	//TODO: get the 
    	in = new BufferedReader(
                new InputStreamReader( new FileInputStream( fileName ) ) );//, "UTF-8" ) );
    }
    
    private String readLine() throws IOException {
    	return in.readLine();
    }

    /**
     * Close text file
     */
    private void closeFile() {
        try {
            in.close();
        } catch( Exception e ) {
        	// Nothing to do in here
        }
    }
    
    @SuppressWarnings("unchecked")
	private List buildRow( String inputLine ) {
        List<Object> fields =new ArrayList<Object>();        
        
        String[] fd = inputLine.split(separator);
        
        // Remove the leading double-quote
        fields.add( fd[0].substring(1) );
        
        fields.add( getObjectValue( fd[1] ) );
        
        if ( fd.length > 2 ) {
        	// Remove the trailing double-quote
        	fields.add( fd[2].substring(0, fd[2].length()-1 ) );
        }
        
        return fields;
    }
    
    @SuppressWarnings("unchecked")
	private void readFile() throws Exception {
		tmapSourceFileName =readLine();
		imageTargetFileName =readLine();
		tmapReturnFileName =readLine();

        List<List> rows =new ArrayList<List>();

        attrs =(Attrs)bof.get( BizObjectFactory.ATTRS );
        attrs.setRows( rows );  
		
		String line;
		do {
			line =readLine();
			
			if ( line != null ) {
				List row =buildRow( line );
			
				rows.add( row );
			}
			
		} while( line != null );
		
		buildHeader(); 
		
    }
    
    /**
     * Convert a String to an object value (Integer, Double or String)
     * @param in
     * @return
     */
    private Object getObjectValue( String in ) {
        Object value;
        
        try {
            value =new Integer( in );
        } catch( Exception e ) {
            
            try {
                value =new Double( in );
            } catch( Exception e2 ) {

                try {
                    value =new String( in );
                } catch( Exception e3 ) {
                    value =new String();
                }
                
            }
        }
        
        return value;
    }
    
    /**
     * Build header info based on data
     * @param attrs
     */
    @SuppressWarnings("unchecked")
	private void buildHeader() throws Exception {
        List<AttrDef> fieldsDef =new ArrayList<AttrDef>();
        
        attrs.setHeader( fieldsDef );
        
        if ( attrs.getRows() != null && attrs.getRows().size() > 0 ) {
        
	    	List row =attrs.getRows().get(0);
	    	
	        AttrDef attrDef = (AttrDef)bof.get( BizObjectFactory.ATTR_DEF );
	        attrDef.setName( JOIN_ID );
	        attrDef.setType( String.class.getName() );
	        fieldsDef.add( attrDef );
	        
	        attrDef = (AttrDef)bof.get( BizObjectFactory.ATTR_DEF );
	        attrDef.setName( VALUE );
	        attrDef.setType( row.get(1) != null ? row.get(1).getClass().getName() : Double.class.getName() );
	        fieldsDef.add( attrDef );      
	        
	        if ( row.size() > 2 ) {
	            attrDef = (AttrDef)bof.get( BizObjectFactory.ATTR_DEF );
	            attrDef.setName( POLYGON_NAME );
	            attrDef.setType(  String.class.getName() );
	            
	            fieldsDef.add( attrDef );
	        }
        }
            
    }
}
